import { asyncRoutes, constantRoutes, lastRoute } from '@/router/index'
import { getMenus } from '@/api/user'

const state = {
  routes: []
}

const mutations = {
  // 设置路由信息到vuex中
  SET_ROUTES: (state, routes) => {
    state.routes = routes
  }
}

// 动态菜单还是定义在前端，后端只会返回有权限的菜单列表，通过遍历服务端的菜单数据来判断出前端的菜单显示还是隐藏
// 这样的好处是服务端无需返回前端菜单相关结构，并且菜单显示又可以通过服务器端来控制，进行菜单的动态控制
// 前端新增页面也无需通过服务端进行菜单添加，遵循了前后端分离原则
function generateRoutes(routes, srvMenus) {
  // 遍历前端
  for (let i = 0; i < routes.length; i++) {
    // 前端的每一个菜单项
    const routeItem = routes[i]
    // 菜单项的显示与隐藏
    var showItem = false
    // 遍历后端
    for (let j = 0; j < srvMenus.length; j++) {
      const srvItem = srvMenus[j]
      // 前后端通过serPath属性来匹配
      if (routeItem.name !== undefined && routeItem.name === srvItem.serPath && srvItem.show === true) {
        showItem = true
        // 显示该菜单项
        routes[i]['hidden'] = false
        break
      }
    }
    if (showItem === false) {
      // 隐藏该菜单项
      routes[i]['hidden'] = true
    }
    // 判断当前菜单项是否有子项 如果有子项就进行递归处理
    if (routeItem['children'] !== undefined && routeItem['children'].length > 0) {
      // 递归
      generateRoutes(routes[i]['children'], srvMenus)
    }
  }
}

const actions = {
  getMenus({ commit }) {
    return new Promise(resolve => {
      // 查询所有的菜单数据
      getMenus(state.token).then(async function(res, roles) {
        // 后端菜单
        const srvMenus = res.data
        var pushRouter = asyncRoutes
        generateRoutes(pushRouter, srvMenus)
        const routeArr = []
        routeArr.push(...constantRoutes)
        routeArr.push(...pushRouter)
        routeArr.push(...lastRoute)
        // 设置菜单到vuex中
        commit('SET_ROUTES', routeArr)
        resolve(routeArr)
      })
    })
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}

